/* $RCSFile: CRMBindable.cs $
 * Apache license v2 2011 by Christian Surieux
 * $Source: ?/CRMWrapper3/CRMBindable.cs $
 * $log$
 * Revision 6 2010/08/06 19:56:31  christian.surieux
 *   Added Log to All cs files
 */

using System;
using System.Diagnostics;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Globalization;

using CrmSdk;
using AddonNice.CRMWrapper;
using AddonNice.CRMWrapper.Design;


namespace AddonNice.CRMWrapper 
{

    /// <summary>
    /// Provides an IList that can be bound directly to a standard .NET Data Grid
    /// </summary>
    public class BindableList : IList<DynEntity>
    {
        PropertyDescriptorCollection _columnDescriptors             =   null;
        List<DynEntity>  _dynEntities                               =   new List<DynEntity>();
        bool    _IsReadOnly                                         =   true;

        public BindableList(CRMWrapperBase w, InternalBusinessEntityCollection BusinessEntities,InternalColumnSet s) 
        {
            // Standard MetaData Service Setup

            // Get the name of the entity
            // Note: We have to convert this to lower because RetrieveEntityMetadata expects the schema name
            string entityName   =   w.Util.ExtractEntityName(BusinessEntities);

            // Get the metadata for the currently list's entity
            // This metadata is used to create a "Property Descriptor Collection"
            EntityInternalMetadata entityData = w.adminRetrieveEntityMetadata(entityName, EntityInternalItems.EntityOnly | EntityInternalItems.IncludeAttributes);

            // Cache locals
            _columnDescriptors = w.StaticCreatePropertyDescriptorCollection(entityData);
            w.Util.ExecForEachDynamicEntity(BusinessEntities,
                delegate(InternalDynamicEntity bu)
                {
                    _dynEntities.Add(new DynEntity(w, bu, _columnDescriptors,s));
                    return true; //continue
                }
                );
        }

        #region BindableListEnumerator Class

        /// <summary>
        /// Enumerator for the Universal Entity List
        /// </summary>
        class BindableListEnumerator : System.Collections.IEnumerator, System.Collections.Generic.IEnumerator<DynEntity> 
        {
            private BindableList _entityList;
            private int _index = -1;

            internal BindableListEnumerator(BindableList entityList) 
            {
                _entityList = entityList;
            }

            public void Dispose()
            {
            }

            public bool MoveNext() 
            {
                // If there are no records or moving forward would go past the total
                // number of available records, return false.
                if (_entityList._dynEntities.Count == 0 || (_index + 1) >= _entityList._dynEntities.Count) {
                    return false;
                }
                _index++;
                return true;
            }

            public void Reset() 
            {
                _index = -1;
            }

            Object IEnumerator.Current 
            {
                get
                {
                    if (_index < 0)
                    {
                        throw new CRMWrapperException("CRMBindable: Current not set");
                    }
                    try
                    {
                        return _entityList[_index];
                    }
                    catch (IndexOutOfRangeException)
                    {
                        throw new InvalidOperationException();
                    }

                }
            }

            public DynEntity Current
            {
                get {
                    return _entityList[_index];
                }
            }
        }

        #endregion

        #region IList<DynEntity> Membres


        public DynEntity this[int index] {
            get {
                return  _dynEntities[index];
            }
            set {
                _dynEntities[index] =   value;
            }
        }

        public int IndexOf(DynEntity item)
        {
            return  _dynEntities.IndexOf(item);
        }

        public void Insert(int index, DynEntity item)
        {
            _dynEntities.Insert(index,item);
        }

        #endregion

        #region ICollection<DynEntity> Membres

        public void Add(DynEntity item)
        {
            _dynEntities.Add(item);
        }

        public bool Contains(DynEntity item)
        {
            return _dynEntities.Contains(item);
        }

        public void CopyTo(DynEntity[] array, int arrayIndex)
        {
            _dynEntities.CopyTo(array,arrayIndex);
        }

        public bool Remove(DynEntity item)
        {
            return _dynEntities.Remove(item);
        }

        #endregion

        #region IEnumerable<DynEntity> Membres

        IEnumerator<DynEntity> IEnumerable<DynEntity>.GetEnumerator()
        {
            return new BindableListEnumerator(this);
        }

        #endregion


        #region IEnumerable Membres
        IEnumerator IEnumerable.GetEnumerator() 
        {
            return new BindableListEnumerator(this);
        }
        #endregion

        #region IList<DynEntity> Membres


        public void RemoveAt(int index)
        {
            _dynEntities.RemoveAt(index);
        }

        #endregion

        #region ICollection<DynEntity> Membres


        public void Clear()
        {
            _dynEntities.Clear();
        }

        public int Count
        {
            get { return _dynEntities.Count; }
        }
        public bool IsReadOnly
        {
            get { return _IsReadOnly; }
            set
            {
                _IsReadOnly = value;
            }
        }
        #endregion
    }
   }